/*
 * Projet industriel VAMP 2012 
 */
package com.vampmobile.android.activity;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Locale;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.content.SharedPreferences;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.vampmobile.R;
import com.vampmobile.android.VampApplication;
import com.vampmobile.android.VampCommon.Commons.KINDS;
import com.vampmobile.android.db.Member;
import com.vampmobile.android.db.Poi;
import com.vampmobile.android.db.VampDatabase;
import com.vampmobile.android.db.VampREST;
import com.vampmobile.android.tools.ActivityParameters;

/**
 * class to display NFC Control FO && AM
 */
public class VampNFCControl extends Activity {

	public static final String TAG = "VampNFCControl";

	public static final int REQUEST_CODE = 1000;
	private NfcAdapter nfcAdapter;
	private Animation mRightAnim;
	private Animation mLeftAnim;
	private PendingIntent mPendingIntent;
	private IntentFilter ndefDetected;
	private ProgressDialog mDialog;
	private ImageView mHomeTitle;
	private ImageView mHomeButton;
	private ImageView mBackButton;
	private ImageView mSearchButton;
	private ImageView mQuitButton;
	private ImageView mAccountButton;

	private final static Long PROGRESS_TIME = Long.valueOf(500);

	/*
	 * method used by clicking on the list of item
	 */
	class ItemClickListener implements OnClickListener {

		private String name = null;
		private Long id = null;
		private KINDS kind = null;

		public ItemClickListener(KINDS kind) {
			super();
			this.kind = kind;
		}

		// case video and music
		public ItemClickListener(KINDS kind, Long id, String name) {
			super();
			this.kind = kind;
			this.id = id;
			this.name = name;
		}

		public void onClick(View mView) {
			switch (kind) {
			case TOOLBAR:
				FrameLayout toolbar = (FrameLayout) findViewById(R.id.toolbar); 
				if (toolbar.getVisibility()!=View.VISIBLE)
					toolbar.setVisibility(View.VISIBLE);
				else
					toolbar.setVisibility(View.GONE);
				break;
			case QUIT:
				android.os.Process.killProcess(android.os.Process.myPid());
				java.lang.System.exit(0);
				finish();
				break;
			case SEARCH:
				break;
			case BACK:
				goHome();
				break;
			case PROFILE_TITLE:
				Intent myIntent = new Intent();
				myIntent.setClass(getApplicationContext(), Profile.class);
				myIntent.setAction(Intent.ACTION_VIEW);
				finish();
				startActivity(myIntent);
				break;
			case HOME_TITLE:
				Intent i = new Intent();
				i.setClass(getApplicationContext(), Home.class);
				i.setAction(Intent.ACTION_VIEW);
				finish();
				startActivity(i);
				break;
			}

		}
	}

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		setTitle(TAG);
		setContentView(R.layout.vampnfc);
		// button of title bar
		mHomeTitle = (ImageView) findViewById(R.id.home_title);
		mHomeTitle.setOnClickListener(new ItemClickListener(KINDS.TOOLBAR));
		// button of toolbar
		mHomeButton = (ImageView) findViewById(R.id.home);
		mHomeButton.setOnClickListener(new ItemClickListener(KINDS.HOME_TITLE));
		mBackButton = (ImageView) findViewById(R.id.back_button);
		mBackButton.setOnClickListener(new ItemClickListener(KINDS.BACK));
		mSearchButton = (ImageView) findViewById(R.id.search);
		mSearchButton.setOnClickListener(new ItemClickListener(KINDS.SEARCH));
		mQuitButton = (ImageView) findViewById(R.id.quit);
		mQuitButton.setOnClickListener(new ItemClickListener(KINDS.QUIT));
		mAccountButton = (ImageView) findViewById(R.id.account);
		mAccountButton.setOnClickListener(new ItemClickListener(KINDS.PROFILE_TITLE));		
	}

	public void goHome() {
		Intent i = new Intent();
		i.setClass(getApplicationContext(), Home.class);
		i.setAction(Intent.ACTION_VIEW);
		finish();
		startActivity(i);
	}
	// new Added
	private void enableNdefExchangeMode() {
		String URL_to_send = null;
		SharedPreferences settings = getSharedPreferences(
				VampApplication.PREFS, Context.MODE_PRIVATE);
		String nfcTag = null;
		Long iIdNFC = null;
		// if I'm sending a poi to someone
		if (ActivityParameters.currentActivity == ActivityParameters.ACTIVITY_POI_DETAIL_NFC
				&& ActivityParameters.poiIdToExchangeNFC != null) {
			iIdNFC = ActivityParameters.poiIdToExchangeNFC;
			ActivityParameters.poiIdToExchangeNFC = null;
			nfcTag = VampREST.getPoiNfcTag(iIdNFC);
		}

		// if I'm requesting a vehicle use
		if (ActivityParameters.currentActivity == ActivityParameters.ACTIVITY_VEHICLE_DETAIL_NFC
				&& ActivityParameters.userRequestIdNFC != null) {
			iIdNFC = ActivityParameters.userRequestIdNFC;
			ActivityParameters.userRequestIdNFC = null;
			nfcTag = VampREST.getVehicleRequestNfcTag(iIdNFC);
		}
		if (nfcTag != null) {
			URL_to_send = nfcTag;
			System.out.println("je vais envoyer URL=" + URL_to_send);
			NdefRecord record = createRecord(URL_to_send);
			NdefMessage message = createMessage(record);
			nfcAdapter.enableForegroundNdefPush(this, message);
			// NfcAdapter.getDefaultAdapter(this).enableForegroundNdefPush(this,
			// message);
			nfcAdapter.enableForegroundDispatch(this, mPendingIntent, null,
					null);
		}
	}

	public class SyncTask extends AsyncTask<String, Integer, Boolean> {

		SyncTask() {

		}

		@Override
		public synchronized Boolean doInBackground(String... args) {
			for (int i = 0; i < PROGRESS_TIME.intValue(); i++) {
				try {
					Thread.sleep(Long.valueOf(10));
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				publishProgress((int) ((i / (float) PROGRESS_TIME.longValue())));
			}
			return true;
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			mDialog.setProgress(values[0]);
		}

		@Override
		protected void onPostExecute(Boolean result) {
			try {
				setResult(RESULT_OK);
				mDialog.dismiss();
				Intent myIntent = new Intent(Intent.ACTION_VIEW);
				myIntent.setClass(getApplicationContext(), Poi.class);
				finish();
				startActivity(myIntent);

			} catch (Exception e) {
				System.out.println(e.getClass().toString());
			}
		}
	}

	public NdefRecord createRecord(String message) {
		byte[] langBytes = Locale.ENGLISH.getLanguage().getBytes(
				Charset.forName("US-ASCII"));
		byte[] textBytes = message.getBytes(Charset.forName("UTF-8"));
		char status = (char) (langBytes.length);
		byte[] data = new byte[1 + langBytes.length + textBytes.length];
		data[0] = (byte) status;
		System.arraycopy(langBytes, 0, data, 1, langBytes.length);
		System.arraycopy(textBytes, 0, data, 1 + langBytes.length,
				textBytes.length);
		message = message.trim();
		System.out.println("je vais envoyer message=" + message);
		NdefRecord rec;
		if (Build.VERSION.SDK_INT >= 14) {
			rec = NdefRecord.createUri(message);
		} else {
			rec = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
					NdefRecord.RTD_TEXT, new byte[0], data);
		}
		return rec;
	}

	public NdefMessage createMessage(NdefRecord record) {
		NdefRecord[] records = new NdefRecord[1];
		records[0] = record;
		System.out.println("*******LE RECORD CONTIENT " + record.toByteArray().length);
		NdefMessage message = new NdefMessage(records);
		return message;
	}

	boolean resolveIntent(Intent intent) {
		Log.i("isAuthenticated", Boolean.toString(VampREST.isAuthenticated()));
		SharedPreferences settings = getSharedPreferences(
				VampApplication.PREFS, Context.MODE_PRIVATE);
		String username = settings.getString("login_useremail", null);
		if (username == null || username.trim().equals("")) {
			Context context = VampApplication.getAppContext();
			Intent myIntent = new Intent(getApplicationContext(), Login.class);
			myIntent.setAction(Intent.ACTION_VIEW);
			myIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
			Bundle bundle = new Bundle();
			bundle.putString("OnlyLogin", "1");
			myIntent.putExtras(bundle);
			context.startActivity(myIntent);
		}
		// Parse the intent
		String action = intent.getAction();
		if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
				|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)
				|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
			System.out.println("je lis du NFC");
			Parcelable[] rawMsgs = intent
					.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
			NdefMessage[] messages;
			String message = "";
			if (rawMsgs != null) {
				messages = new NdefMessage[rawMsgs.length];
				for (int i = 0; i < rawMsgs.length; i++) {
					messages[i] = (NdefMessage) rawMsgs[i];
					NdefRecord record = messages[i].getRecords()[i];
					message = getTextData(record.getPayload());
					System.out.println("***********J'ai recu le message NFC : " + message);
					if (message.contains(VampDatabase.POI_TABLE))
						return processReceivePoi(message);
					if (message.contains(VampDatabase.USERREQUEST_TABLE))
						return processReceiveRequest(message);
				}
			}

			else {

				System.out.println("je n'ai pas lu de NFC 1");
			}
		} else {
			System.out.println("je n'ai pas lu de NFC 2");

		}
		return false;
	}
	boolean processReceivePoi(String message) {
		message = message.substring(message.indexOf("poi", 0), message.length());
		Poi p = VampREST.getPoiByNfcTag(message);
		System.out.println("mon poi=" + p.title);
		if (p != null) {
			Intent myIntent = new Intent();
			myIntent.setAction(Intent.ACTION_VIEW);
			myIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
			//p=VampREST.addPoiPrivateUserCopy(p);
			if (p!=null) {
				Toast.makeText(this, "Poi added successfully !",
						Toast.LENGTH_LONG).show();
				ActivityParameters.poiId = p.getId();
				ActivityParameters.currentActivity = ActivityParameters.ACTIVITY_POI_DETAIL;
				VampDatabase.getInstance(getApplicationContext()).getDbHelper()
				.initPoi();
				VampDatabase.getInstance(getApplicationContext()).getDbHelper()
				.initLinks();
				myIntent.setClass(getApplicationContext(), PoiDetail.class);
				
			} else {
				Toast.makeText(this, "Error", Toast.LENGTH_LONG)
						.show();
				ActivityParameters.currentActivity = ActivityParameters.ACTIVITY_HOME;
				myIntent.setClass(getApplicationContext(), Home.class);
			}
			startActivity(myIntent);
			finish();
			return true;
		}
		return false;
	}
	boolean processReceiveRequest(String message) {
		message = message.substring(message.indexOf("userequest", 0), message.length()-1);
		JSONObject o = VampREST.getUserRequestByNfcTag(message);
		if (o != null) {
			 System.out.println("received user request =" + o.toString());
			 o = o.optJSONObject(VampDatabase.VEHICLE_ID_COL);
			 Member m = new Member(o);
			 String vehicleDesc = "";
			 try {
				vehicleDesc = (o)
						 .getString(VampDatabase.VEHICLE_DESCRIPTION_COL);
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			 String timestamp = "";
			 try {
				timestamp = o.getString(VampDatabase.USERREQUEST_TIMESTAMP_COL);
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			 if (m.email!=null) {
				AlertDialog alertDialog = new AlertDialog.Builder(this)
						.create();
				alertDialog.setTitle("Vehicle request");
				alertDialog.setMessage(m.name+ " "+m.firstname+ "has requested"+"/n"
				+" vehicle "+vehicleDesc+" at "+timestamp);
				alertDialog.setButton("OK",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog,
									int which) {
								// here you can add functions
							}
						});
				alertDialog.setIcon(R.drawable.icon);
				alertDialog.show();
				return true;
			 }
			 
		}
		return false;
	}

	String getTextData(byte[] payload) {
		String texteCode = ((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16";
		int langageCodeTaille = payload[0] & 0077;
		try {
			return new String(payload, langageCodeTaille + 1, payload.length
					- langageCodeTaille - 1, texteCode);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return "";
	}

	@Override
	public void onResume() {
		super.onResume();
		nfcAdapter = NfcAdapter.getDefaultAdapter(this);
		mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
				getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

		// Intent filters for exchanging over p2p.
		ndefDetected = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
		try {
			ndefDetected.addDataType("text/plain");
		} catch (MalformedMimeTypeException e) {
		}

		// Start animation
		LinearLayout phoneNfcLeft=(LinearLayout)findViewById(R.id.layout_nfc_left);
		LinearLayout phoneNfcRight=(LinearLayout)findViewById(R.id.layout_nfc_right);
		phoneNfcLeft.bringToFront();
		mLeftAnim = AnimationUtils.loadAnimation(this, R.anim.push_right);
		
		mRightAnim = AnimationUtils.loadAnimation(this, R.anim.push_left);
		phoneNfcLeft.startAnimation(mLeftAnim);
		phoneNfcRight.startAnimation(mRightAnim);

		((TextView) findViewById(R.id.text_nfc_searching))
				.setText("Processing...");
		mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
				this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

		// C'est dans cette méthode qu'on récupère le tag et qu'on l'envoie :
		enableNdefExchangeMode();
		// D'abord, on vérifie qu'on est en réception
		Intent intent = getIntent();
		resolveIntent(intent);
		if (!resolveIntent(intent)) {
			// si un tag a été détecté, l'activité a été finie :
			// On va essayer d'envoyer le tag
			mDialog = new ProgressDialog(VampNFCControl.this);

			mDialog.setMax(PROGRESS_TIME.intValue());
			mDialog.setMessage("Sending URL...");
			mDialog.setIndeterminate(false);
			mDialog.setCancelable(false);
			// Juste pour montrer qu'il se passe quelque chose :-)
			SyncTask progress = (SyncTask) new SyncTask().execute();
			mDialog.show();
		}
	}

	@Override
	public void onPause() {
		super.onPause();
		nfcAdapter.disableForegroundDispatch(this);
		// NfcAdapter.getDefaultAdapter(this).disableForegroundNdefPush(this);
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			setResult(RESULT_CANCELED);
			finish();
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

}
